assume cs:code

; 求和 0123h,0456h,0789h,089Ah,0abch,0bcdh,0cdeh,0ef0h
code segment
	; 定义字类型数据
	      dw   0123h,0234h,0456h,0567h,0789h,089ah,09abh,0abch
	start:mov  bx,0
	      mov  ax,0
	      mov  cx,0
	s:    add  ax,cs:[bx]
	      add  bx,2
	      loop s
	      mov  ax,4c00h
	      int  21h
code ends
; 此处end通知编译程序的入口
end start

; 依次用0:0~0:15内存单元中的数据改写程序中的数据
code6_1 segment
	        dw   0123h,0456h,0789h,089Ah,0abch,0bcdh,0cdeh,0ef0h
	start:  mov  ax,0
	        mov  ds,ax
	        mov  bx,0
	        mov  cx,8
	s:      mov  ax,[bx]
	        mov  cs:[bx],ax
	        add  bx,2
	        loop s

	        mov  ax,4c00h
	        int  21h
code6_1 ends

; 依次用0:0~0:15内存单元中的数据改写程序中的数据，使用栈实现
code6_2 segment
	        dw   0123h,0456h,0789h,089Ah,0abch,0bcdh,0cdeh,0ef0h
	        dw   0,0,0,0,0,0,0,0,0,0                            	;10个字单元作为栈空间，地址范围CS:[10H]~CS:[23H]
	start:  mov  ax,cs
	        mov  ss,ax
	        mov  sp,24H                                         	;指向栈顶，栈空间范围的最大值+1
        
	        mov  ax,0
	        mov  ds,ax
	        mov  bx,0
	        mov  cx,8
	s:      push [bx]
	        pop  cs:[bx]
	        add  bx,2
	        loop s

	        mov  ax,4c00h
	        int  21h
code6_2 ends

; 在程序中使用多个段
assume cs:code64,ds:data64,ss:stack64
data64 segment
	       dw 0123h,0456h,0789h,089Ah,0abch,0bcdh,0cdeh,0ef0h
data64 ends
stack64 segment
	        dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack64 ends
code64 segment
	start: mov  ax,stack64
	       mov  ss,ax
	       mov  sp,20h

	       mov  ax,data64
	       mov  ds,ax

	       mov  bx,0
	       mov  cx,8
	s:     push [bx]
	       add  bx,2
	       loop s

	       mov  bx,0
	       mov  cx,8
	s2:    pop  [bx]
	       add  bx,2
	       loop s2

	       mov  ax,4c00h
	       int  21h
code64 ends
; 实验 五

assume cs:code65,ds:data65,ss:stack65

data65 segment
	       dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data65 ends

stack65 segment
	        dw 0,0,0,0,0,0,0,0
stack65 ends

code65 segment
	start: mov  ax,stack65
	       mov  ss,ax
	       mov  sp,16
	       mov  ax,data65
	       mov  ds,ax

	       push ds:[0]
	       push ds:[2]
	       pop  ds:[0]
	       pop  ds:[2]

	       mov  ax,4c00h
	       int  21h
code65 ends
end start

; 将段a,b中的数据依次相加结果放入段c
a segment
	  db 1,2,3,4,5,6,7,8
a ends
b segment
	  db 1,2,3,4,5,6,7,8
b ends
c segment
	  db 0,0,0,0,0,0,0,0
c ends
code6_5 segment
	start:  mov  ax,a
	        mov  ds,ax
	        mov  ax,b
	        mov  es,ax
	        mov  ax,c
	        mov  ss,ax

	        mov  bx,0
	        mov  cx,8
	s:      mov  al,ds:[bx]
	        add  al,es:[bx]
	        mov  ss:[bx],al
	        inc  bx
	        loop s

	        mov  ax,4c00h
	        int  21h
code6_5 ends
end start

; 使用push命令将a段的前8个字型数据逆序存放到b段
assume cs:code6_6
a segment
	  dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh
a ends
b segment
	  db 0,0,0,0,0,0,0,0	; 栈范围00h~0fh
b ends
code6_6 segment
	start:  mov  ax,a
	        mov  ds,ax
	        mov  ax,b
	        mov  ss,ax
	        mov  sp,10h
	        mov  bx,0
	        mov  cx,8
	s:      push ds:[bx]
	        add  bx,2
	        loop s

	        mov  ax,4c00h
	        int  21h
code6_6
end start

; 将第一个字符串转换为大写，第二个字符串转换为小写
assume cs:code67,ds:data67
data67 segment
	       db 'This is a String'
	       db 'This is a String'
data67 ends
data67_2 segment
	         db '0000 00 0 000000'
	         db '0000 00 0 000000'
data67_2 ends
code67 segment
	start: mov  ax,data67
	       mov  ds,ax
	       mov  ax,data67_2
	       mov  es,ax

	       mov  bx,0
	       mov  cx,16
	s:     mov  es:[bx],ds:[bx]
	       and  es:[bx],11011111B
	       mov  dx,bx
	       add  dx,10H
	       mov  es:[dx],ds:[dx]
	       or   es:[dx],00100000B
	       inc  bx
	       loop s

	       mov  ax,4c00h
	       int  21h
code67 ends
; 采用[bx+idata]方式处理数组数据
code67_2 segment
	start:   mov  ax,data67
	         mov  ds,ax
	         mov  ax,data67_2
	         mov  es,ax
        
	         mov  bx,0
	         mov  cx,16
	s:       mov  es:[bx],ds:[bx]
	         and  es:[bx],11011111B
	         mov  es:[bx+10H],ds:[bx+10H]
	         or   es:[bx+10H],00100000B
	         inc  bx
	         loop s

	         mov  ax,4c00h
	         int  21h
code67_2 ends
end start

; 将datasg段中的每个单词的前4个字母改为大写
assume cs:codesg,ds:datasg,ss:stacksg
stacksg segment
	        dw 0,0,0,0,0,0,0,0
stacksg ends
datasg segment
	       db '1. hello        '
	       db '2. alice        '
	       db '3. masm!        '
	       db '4. windows      '
datasg ends
codesg segment
	start: mov  ax,stacksg
	       mov  ss,ax
	       mov  sp,10H
	       mov  ax,datasg
	       mov  ds,ax
	       mov  cx,4
	       mov  si,0
	s:     push cx
	       mov  cx,4
	       mov  bx,3
	s1:    mov  al,[si+bx]
	       and  al,0DFH
	       mov  [si+bx],al
	       inc  bx
	       loop s1
	       add  si,10h
	       pop  cx
	       loop s

	       mov  ax,4c00h
	       int  21h
codesg ends
end start

; 实验7 寻址方式在结构化数据访问中的应用
assume cs:codesg,ds:datasg,ss:stacksg
datasg segment
        ; 21个数据 年份
        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
        db '1993','1994','1995'
        ; 21个dword数据 收入
        dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
        dd 345980,590827,803530,1183000,1843000,2789000,3753000,4649000,5937000
        ; 21个word数据 雇员
        dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
        dw 11542,14430,15257,17800
datasg ends
table segment
        db 21 dup('year summ ne ?? ')
table ends
stacksg segment
        dw 0,0,0,0,0,0,0,0
stacksg ends
codesg segment
start:  
        mov ax,table
        mov ds,ax
        mov ax,datasg
        mov es,ax
        mov ax,stacksg
        mov ss,ax
        mov sp,10h
        ; 
        mov bx,0
        mov cx,21
        mov di,0
s:      
		push cx
        ; year
        mov cx,4
        mov si,0
s1:     
		mov byte ptr [bx].0[si],es:[di][si]
		inc si
        loop s1
		; summery
		mov dword [bx].5,es:84[di]
		; people
		mov word ptr [bx].a,es:168[di]
		; 计算人均
		mov word ptr ax,[bx].5
		mov word ptr dx,[bx].7
		div word ptr [bx].a
		mov [bx].d,ax

        add di,4h
        add bx,10h
        pop cx
        loop s

		mov ax,4c00h
		int 21h
codesg ends
end start

; 实验8 分析一个奇怪的程序
; 是否能够正常返回
; 可正常返回，s2位置的跳转对应代码写入s后，再次执行时将跳转到cs:[0]位置
; 原因：编译完成后jmp short s1机器码为位移偏移到s1位置，该跳转代码放到s后再执行则跳转到前面的mov ax,4c00h
assume cs:codesg
codesg segment
		mov ax,4c00h
		int 21h
start:	mov ax,0
	s:	nop
		nop
		mov di,offset s
		mov si,offset s2
		mov ax,cs:[si]
		mov cs:[di],ax
	
	s0:	jmp short s
	
	s1:	mov ax,0
		int 21h
		mov ax,0
	
	s2:	jmp short s1
		nop
codesg ends
end start

